import Request from '@/utils/luch-request/index.js'
import {
  api,
  env
} from '@/config/config'
import Cache, {
  Keys
} from '@/utils/cache.js'
import {
  getAccessToken
} from '@/utils/getAccessToken.js'

const http = new Request();

let expireTokenCache = [] // 储存过期的token

class Ajax {

  ajax(options = {}) {
    return http.request({
      method: options.method, // 请求方法必须大写
      url: options.url,
      data: options.data,
      // #ifdef MP-ALIPAY || MP-WEIXIN
      timeout: 30000, // 仅微信小程序（2.10.0）、支付宝小程序支持
      // #endif
      params: options.params,
      // 注：如果局部custom与全局custom有同名属性，则后面的属性会覆盖前面的属性，相当于Object.assign(全局，局部)
      custom: {
        isJson: options.isJson,
        needToken: options.needToken
      }, // 自定义参数
    })
  }
}


/** 请求之前拦截 */
http.interceptors.request.use(async (config) => {
  // console.log(config)
  // 可使用async await 做异步操作

  /** 处理url */
  if (/^\/base\/.*/.test(config.url)) {
    config.url = config.url.replace('/base/', '/')
    config.baseURL = api.base;
  } else if (/^\/zhibo\/.*/.test(config.url)) {
    config.url = config.url.replace('/zhibo/', '/')
    config.baseURL = api.zhibo;
  } else {
    config.baseURL = api.buyer;
  }
  //设置header信息
  //uniapp统一设置头client_type=UNIAPP
  //因为目前移动端没有适合的技术支持拖拽验证
  //在服务器端判断了如果client_type=UNIAPP，则强制使用验证码验证
  config.header = {
    ...config.header,
    client: 'MINI',
    clientType: 'UNIAPP',
    uuid: uni.getStorageSync(Keys.uuid)
  }

  //如果需要json传递方式
  if (config.custom.isJson) {
    config.header = {
      ...config.header,
      'Content-Type': 'application/json'
    }
  } else {
    config.header = {
      ...config.header,
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  }

  //如果需要Token
  if (config.custom.needToken) {
    //accessToken
    const accessToken = uni.getStorageSync(Keys.accessToken);
    //refreshToken
    const refreshToken = uni.getStorageSync(Keys.refreshToken);
    //tokenExpTime
    const tokenExpTime = uni.getStorageSync(Keys.tokenExpTime);
    //设置header信息
    config.header = {
      ...config.header,
      Authorization: accessToken,
    }
    //#ifdef H5
    //超过20分钟获取新token
    if (refreshToken) {
      if ((new Date().getTime() - tokenExpTime) / 1000 > 60 * 20) {
        try {
          console.log('换票========>')
          const {
            statusCode,
            data,
          } = await getAccessToken()
          console.log('结果========>')
          console.log(statusCode)
          if (statusCode === 200) {
            expireTokenCache = []
            //设置header信息
            config.header = {
              ...config.header,
              Authorization: data.accessToken,
            }
          } else {
            // 其他情况，可能refreshToken过期了等等，请根据自身逻辑处理
            console.log('refreshToken过期了，清空登录信息');
            cleanAll();
          }
        } catch (e) {
          cleanAll();
          console.log(e);
          // 可能由于网络原因通过refreshToken 获取accessToken失败了;
          //可以根据自身逻辑处理，我这里直接放弃本次请求，会进入interceptors.response的错误拦截函数
          return Promise.reject(config)
        }
      }
    }
    //#endif
  }

  //设置请求参数
  if (config.params) {
    //config.data = config.params
  }

  // console.log('请求地址=' + config.baseURL + config.url)
  // console.log('请求参数=' + JSON.stringify(config.params))
  return config
}, config => {
  // 可使用async await 做异步操作
  return Promise.reject(config)
})

// 必须使用异步函数，注意
http.interceptors.response.use(async (response) => {
  /* 请求之后拦截器。*/

  return response.data;
}, (response) => {
  //如果是403，则清空登录信息
  if (response.statusCode == 403) {
    console.log('如果是403，则清空登录信息');
    cleanAll();
  } else if (response.statusCode == 500 && response.data.code != '153') {
    uni.showToast({
      title: response.data.message,
      icon: 'none',
      duration: 2000,
    })
  }
  return Promise.reject(response)
})

//清空登录信息
function cleanAll() {
  console.log('清空登录信息')
  uni.$emit('logout', {
    msg: '退出登录消息'
  })
  Cache.removeItem(Keys.user);
  Cache.removeItem(Keys.accessToken);
  Cache.removeItem(Keys.refreshToken);
  Cache.removeItem(Keys.wxauth);
  Cache.removeItem(Keys.loginResult);
}

export default new Ajax();

export const Method = {
  GET: 'GET',
  POST: 'POST',
  PUT: 'PUT',
  DELETE: 'DELETE',
};
